﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numeric;
using System.Globalization;
using AdvanceLib.ScriptCore;
using AdvanceLib.ScriptCore.DebugCore;
using AdvanceLib.ClassExtensions;
using AdvanceLib.Extension.XseScript.DebugPasses;

namespace AdvanceLib.Extension.XseScript.DebugPasses
{
    public class ParameterTypePass : CommandPass
    {
        #region Constructors
        public ParameterTypePass(XseExtensionProvider provider)
        {
            this._provider = provider;
            this._database = provider.Database;
        }
        #endregion

        #region Fields
        private XseExtensionProvider _provider;

        private ScriptDatabase _database;
        private CommandData _command;

        private ParameterValidationPass _validator;
        #endregion

        #region IterativeCommandDebugger
        public override void Pass(DebugResult result, string linePart)
        {
            if (this._validator == null)
            {
                //Lazy Initialization of this._validator
                this._validator = (this._provider.Debugger as Debugger).GetDebugger<ParameterValidationPass>();
            }
            if (this.CurrentLinePartIndex == 0)
            {
                this._command = this._database.GetCommandDataByName(linePart);
            }
            if (!this._validator.IsParameterInvalid(this.CurrentLineIndex, this.CurrentLinePartIndex) &&
                this.CurrentLinePartIndex > 0 && this._command != null)
            {
                long paramValue = long.MinValue;
                bool parseSucceed = false;

                parseSucceed = linePart.TryParse(ref paramValue);        

                if (parseSucceed &&
                    this._command.Parameters.Count > this.CurrentLinePartIndex)
                {
                    int byteCount = this._command.Parameters[this.CurrentLinePartIndex - 1];
                    long maxValue = (long)Math.Pow(2, 8 * byteCount);

                    if (paramValue >= maxValue)
                    {
                        result.Errors.Add(new DebugError()
                        {
                            Line = this.CurrentLineIndex,
                            Message = "Invalid parameter " + this.CurrentLinePartIndex.ToString() + ": Parameter has to be lower than " + byteCount.ToString() + " byte(s)"
                        });
                    }
                }
            }
        }
        #endregion
    }
}
